package cn.rengy.web.framework.wxmp.user;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import cn.hutool.core.bean.BeanUtil;
import cn.rengy.tpa.wxmp.exception.WeChatException;
import cn.rengy.tpa.wxmp.token.AccessToken;
import cn.rengy.tpa.wxmp.user.LanguageType;
import cn.rengy.tpa.wxmp.user.User;
import cn.rengy.tpa.wxmp.user.UserManager;
import cn.rengy.web.framework.cache.CacheService;
import cn.rengy.web.framework.id.IdGenerator;
import cn.rengy.web.framework.sql.DbService;
import cn.rengy.web.framework.sys.user.AuthTable;
import cn.rengy.web.framework.sys.user.entity.UserAuth;
import cn.rengy.web.framework.sys.user.service.UnionUserService;
import cn.rengy.web.framework.wxmp.WxAppService;
import cn.rengy.web.framework.wxmp.token.AccessTokenCacheService;
/**
 *
 */
@Service
public class WxUserService {
	@Autowired
	private DbService dbService;
	@Autowired
	CacheManager cacheManager;
	@Autowired
	private WxAppService wxAppService; 
	private static Logger logger = LoggerFactory.getLogger(WxUserService.class);
	@Autowired
	private AccessTokenCacheService accessTokenCacheService;
	
	@Autowired
	private UnionUserService unionUserService;
	@Autowired
	private IdGenerator idGenerator;
	@Autowired
	private CacheService cacheService;
	
	
	public String getUserIdByOpenid(String openid,String appid) {
		return this.dbService.querySingleColumn("select_get_user_id_by_openid", String.class, openid,appid);
	}
	/**
	 * 新增微信用户信息
	 * @param openid
	 * @param appid
	 * @return 统一用户id
	 */
	@Transactional
	public UserAuth save(WxUserPO wxUser) {
		UserAuth userAuth=null;
		String openid=wxUser.getOpenid();
		String appid=wxUser.getAppid();
		String unionid=wxUser.getUnionid();
		//WxUserPO dbWxUser=getWxUser(openid,appid);//查询数据库是否有微信用户信息
		Long wuid=this.dbService.querySingleColumn("select_get_wuid", Long.class, openid,appid);
		Long user_id=null;//统一用户id
		if(wuid==null){
			//新增微信用户
			wuid=(Long)idGenerator.generateId();
			wxUser.setId(wuid);
			this.dbService.updateBeanParameter("insert_wx_user", wxUser);
			//根据unionid关联的wuid查询是否已有统一用户
//			if(StringUtils.isNotBlank(unionid)) {
//				user_id=this.dbService.querySingleColumn("select_get_union_userid", String.class, unionid);
//			}
		}else {//数据库有微信用户信息
			//wxUserMap.put("id", wuid);
			//查询用户绑定信息
			userAuth=unionUserService.getUnionUserByAuthId(wuid);
		}
		if(userAuth==null) {//认证关系为空
			if(StringUtils.isNotBlank(unionid)) {
				user_id=this.dbService.querySingleColumn("select_get_union_userid", Long.class, unionid);
			}
			//新增统一用户
			if(user_id==null) {
				//新增统一用户
				Map<String,Object> user=new HashMap<String,Object>();
				user_id=(Long)idGenerator.generateId();
				user.put("id", user_id);
				user.put("nickname", wxUser.getNickname());
				user.put("sex", wxUser.getSex());
				user.put("headimgurl", wxUser.getHeadimgurl());
				user.put("city", wxUser.getCity());
				user.put("province", wxUser.getProvince());
				user.put("country", wxUser.getCountry());
				user.put("openid", openid);
				user.put("create_time", new Date());
				dbService.updateMapParameter("insert_sys_user", user);
			}
			//新增认证关系
			this.dbService.update("insert_sys_user_auth_rel", wuid,user_id,AuthTable.wx_user.toString());
			userAuth=new UserAuth();
			userAuth.setAuth_id(wuid);
			userAuth.setUser_id(user_id);
			userAuth.setAuth_table(AuthTable.wx_user.toString());
		}
		return userAuth;
	}
	
	public WxUserPO getWxUser(String openid,String appid){
		Assert.notNull(openid,"openid不能为空");
		//TODO 可以考虑MD5(appid+openid)
		//String key=openid;//appid+openid
		//return cacheService.getCache("wxUserCache", key, new Callable<WxUser>() {
	    //    @Override
	    //    public WxUser call() throws Exception {
				return dbService.queryForBean("select_get_wx_user", WxUserPO.class, openid,appid);
	     //   }
	    //});
	}
	
	public void synchronizeUserInfo(Map<String,Object> paramMap) throws WeChatException {
		Long id=MapUtils.getLong(paramMap, "id");
		WxUserPO u=this.dbService.queryForBean("select_get_wx_user_byid", WxUserPO.class, id);
		String openid=u.getOpenid();
		String appid=u.getAppid();
		AccessToken accessToken=accessTokenCacheService.getAccessToken(appid);
		UserManager userManager=new UserManager(accessToken);
		User user=userManager.getUserInfo(openid,LanguageType.zh_CN);
		WxUserPO wxUser=new WxUserPO();
		BeanUtil.copyProperties(user, wxUser);
		wxUser.setAppid(appid);
		wxUser.setId(id);
		this.dbService.updateBeanParameter("update_wx_user",wxUser);
	}
	
	public void synchronizeAllUser(String appid) throws WeChatException {
		//WxApp wxApp=wxAppService.getApp(appid);
		AccessToken accessToken=accessTokenCacheService.getAccessToken(appid);
		UserManager userManager=new UserManager(accessToken);
		List<String> openidList=userManager.allSubscriber();
		if(openidList!=null){
			for(String openid:openidList){
				User user=userManager.getUserInfo(openid,LanguageType.zh_CN);
				WxUserPO wxUser=new WxUserPO();
				BeanUtil.copyProperties(user, wxUser);
				wxUser.setAppid(appid);
				WxUserPO dbUser=getWxUser(openid,appid);
				if(dbUser==null) {//新增
					//新增微信用户
					Long wuid=(Long)idGenerator.generateId();
					wxUser.setId(wuid);
					this.dbService.updateBeanParameter("insert_wx_user", wxUser);
				}else {//更新
					this.dbService.updateBeanParameter("update_wx_user",wxUser);
				}
			}
			openidList.clear();
		}
	}
}
